package com.codeyang.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codeyang.constans.Constants;
import com.codeyang.domain.DictData;
import com.codeyang.domain.DictType;
import com.codeyang.dto.DictTypeDto;
import com.codeyang.mapper.DictDataMapper;
import com.codeyang.mapper.DictTypeMapper;
import com.codeyang.service.DictTypeService;
import com.codeyang.vo.DataGridView;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 描述: TO-删除标志-DO
 *
 * @author CodeYang_Site
 * @version 2021/4/20 15:34
 */
@Service
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements DictTypeService {

    @Autowired
    private DictTypeMapper dictTypeMapper;

    @Autowired
    private DictDataMapper dictDataMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public DataGridView lisPage(DictTypeDto dictTypeDto) {
        // 分页包装
        Page<DictType> page = new Page<>(dictTypeDto.getPageNum(),dictTypeDto.getPageSize());
        // 根据修改时间做分页排序
        page.addOrder(OrderItem.desc(DictType.COL_UPDATE_TIME));
        QueryWrapper<DictType> qw = new QueryWrapper<>();
        // like 查询  like 支持条件参数 条件成立时执行
        qw.like(StringUtils.isNotBlank(dictTypeDto.getDictName()), DictType.COL_DICT_NAME, dictTypeDto.getDictName());
        qw.like(StringUtils.isNotBlank(dictTypeDto.getDictType()), DictType.COL_DICT_TYPE, dictTypeDto.getDictType());
        // 精准查询
        qw.eq(StringUtils.isNotBlank(dictTypeDto.getStatus()), DictType.COL_STATUS, dictTypeDto.getStatus());
        //范围查询
        qw.between(dictTypeDto.getBeginTime() != null && dictTypeDto.getEndTime() != null, DictType.COL_CREATE_TIME, dictTypeDto.getBeginTime(), dictTypeDto.getEndTime());

        dictTypeMapper.selectPage(page, qw);

        return new DataGridView(page.getTotal(), page.getRecords());
    }




    @Override
    public boolean saveDictType(DictTypeDto dictTypeDto) {
        // dto 负责传输数据 entity 负责 insert
        // 参数处理
        DictType dictType = new DictType();
        // spring copy 当字段的名称与类型完全匹配时才能完成属性的拷贝
        BeanUtils.copyProperties(dictTypeDto, dictType);
        // 创建时间,创建人
        dictType.setCreateTime(new Date());
        dictType.setCreateBy(dictTypeDto.getSimpleUser().getUserName());
        // 修改时间
        dictType.setUpdateTime(dictType.getCreateTime());
        // 修改人在新增时不需要写
        // 返回值处理
        return dictTypeMapper.insert(dictType) > 0;
    }


    /**
     * 使用id来修改字典数据
     * @param dictTypeDto
     * @return
     */
    @Override
    public boolean updateDictType(DictTypeDto dictTypeDto) {

        // 参数处理
        DictType dictType = new DictType();
        // spring copy 同名数据
        BeanUtils.copyProperties(dictTypeDto, dictType);
        // 修改人和修改时间
        dictType.setUpdateTime(new Date());
        dictType.setUpdateBy(dictTypeDto.getSimpleUser().getUserName());


        return dictTypeMapper.updateById(dictType) > 0;
    }

    /**
     * 同步缓存--更新缓存-缓存所有的字典
     */
    @Override
    public void dictCacheAsync() {
        // 使用redis 远端缓存 + 本地缓存
        // key dictType  value : List<DictData>
        // 两种策略 1 查询全部的字典类型 2 通过类型查询缓存
        Map<String, List<DictData>> dictDataCache = new HashMap<>();
        // 全查询
        List<DictData> dictDataList = dictDataMapper.selectList(null);
        // 构建 字典对应树
        for (DictData dictData : dictDataList) {
            // key
            String dictType = dictData.getDictType();
            List<DictData> dictDatas = null;
            // 判断
            if (dictDataCache.containsKey(dictType)){
                // 获取 对应类型的val
                dictDatas = dictDataCache.get(dictType);

            }else{
                // 创建
                dictDatas = new ArrayList<>();
                dictDataCache.put(dictType,dictDatas);
            }
            // 操作
            // 将查询出来的  --- 缓存加入
            dictDatas.add(dictData);

        }

        // 将查询出来的缓存存储到redis中
        // 根据不同的key 存储不同的val
        dictDataCache.forEach((type,data)->{
            //存储的处理 加上类似文件夹操作
            redisTemplate.opsForValue().set(Constants.DICT_CACHE_PREFIX+type, JSON.toJSONString(data));
        });
    }

}
